Completed
Pull Request — master (#34)
by Sander
01:06
created

$j.ready   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 5
rs 9.4285
1
/* global API */
2
var $j = jQuery.noConflict();
3
4
$j(document).ready(function () {
5
    var _this = this;
6
    Array.prototype.findUrl = function(match) {
0 ignored issues
show
Compatibility Best Practice introduced by
You are extending the built-in type Array. This may have unintended consequences on other objects using this built-in type. Consider subclassing instead.
Loading history...
7
        return this.filter(function(item){
8
            return typeof item == 'string' && item.indexOf(match) > -1;
9
        });
10
    };
11
12
    function removePasswordPicker() {
13
        $j('.passwordPickerIframe').remove();
14
    }
15
16
    _this.removePasswordPicker = removePasswordPicker;
17
18
    function enterLoginDetails(login) {
19
        var username = (login.username.trim() !== '' ) ? login.username : login.email;
20
21
        fillPassword(username, login.password);
22
        if ($j('.passwordPickerIframe').is(':visible')) {
23
            removePasswordPicker();
24
        }
25
    }
26
27
    _this.enterLoginDetails = enterLoginDetails;
28
29
30
    function showPasswordPicker(form) {
31
        if ($j('.passwordPickerIframe').length > 1) {
32
            return;
33
        }
34
        var loginField = $j(form[0]);
35
        var loginFieldPos = loginField.offset();
36
        var position = $j(form[1]).position();
0 ignored issues
show
Unused Code introduced by
The assignment to variable position seems to be never used. Consider removing it.
Loading history...
37
        var passwordField = $j(form[1]);
38
        var passwordFieldPos = passwordField.offset();
39
40
        var left = loginFieldPos.left;
41
        var top = loginFieldPos.top;
42
43
        if (passwordFieldPos.top > loginFieldPos.top) {
44
            //console.log('login fields below each other')
45
            top = passwordFieldPos.top + passwordField.height() + 10;
46
47
        } else {
48
            // console.log('login fields next to each other')
49
            top = top + loginField.height() + 10;
50
        }
51
52
53
        var pickerUrl = API.extension.getURL('/html/inject/password_picker.html');
54
55
        var picker = $j('<iframe class="passwordPickerIframe" scrolling="no" height="400" width="350" frameborder="0" src="' + pickerUrl + '"></iframe>');
56
        picker.css('position', 'absolute');
57
        picker.css('left', left);
58
        picker.css('z-index', 999);
59
        picker.css('top', top);
60
        $j('body').append($j(picker));
61
        // picker.css('width', $j(form).width());
62
        $j('.passwordPickerIframe:not(:last)').remove();
63
    }
64
65
    function createFormIcon(el, form) {
66
        var offset = el.offset();
0 ignored issues
show
Unused Code introduced by
The assignment to variable offset seems to be never used. Consider removing it.
Loading history...
67
        var width = el.width();
68
        var height = el.height() * 1;
69
        var margin = (el.css('margin')) ? parseInt(el.css('margin').replace('px', '')) : 0;
0 ignored issues
show
Unused Code introduced by
The variable margin seems to be never used. Consider removing it.
Loading history...
70
        var padding = (el.css('padding')) ? parseInt(el.css('padding').replace('px', '')) : 0;
0 ignored issues
show
Unused Code introduced by
The variable padding seems to be never used. Consider removing it.
Loading history...
71
72
        var pickerIcon = API.extension.getURL('/icons/icon.svg');
73
        $j(el).css('background-image', 'url("' + pickerIcon + '")');
74
        $j(el).css('background-repeat', 'no-repeat');
75
        $j(el).css('background-position', 'right 3px center');
76
77
78
        function onClick(e) {
79
            e.preventDefault();
80
            var offsetX = e.offsetX;
81
            var offsetRight = (width - offsetX);
82
            if (offsetRight < height) {
83
                showPasswordPicker(form);
84
            }
85
        }
86
87
        // $j(el).bind('click', onClick);
88
        $j(el).click(onClick);
89
90
    }
91
92
    function createPasswordPicker(form) {
93
        for (var i = 0; i < form.length; i++) {
94
            var el = $j(form[i]);
95
            createFormIcon(el, form);
96
97
        }
98
    }
99
100
    function formSubmitted(fields) {
101
        var user = fields[0].value;
102
        var pass = fields[1].value;
103
        var params = {
104
            username: user,
105
            password: pass
106
        };
107
        //Disable password mining
108
        //$j(fields[1]).attr('type', 'hidden');
109
        API.runtime.sendMessage(API.runtime.id, {method: "minedForm", args: params});
110
111
    }
112
113
    function inIframe() {
114
        try {
115
            return window.self !== window.top;
116
        } catch (e) {
117
            return true;
118
        }
119
    }
120
121
    function showDoorhanger(data) {
122
        var buttons = data.buttons;
123
        data = data.data;
124
        if (inIframe()) {
125
            return;
126
        }
127
        var doorhanger_div = $j('<div id="password-toolbar" style="display: none;">');
128
        $j('<span>', {
129
            class: 'toolbar-text',
130
            text: data.title + ' ' + data.username + ' at ' + data.url
131
        }).appendTo(doorhanger_div);
132
133
134
        $j.each(buttons, function (k, button) {
135
            var html_button = $j('<button class="passman-btn passnman-btn-success"></button>').text(button.text);
136
            html_button.click(button.onClickFn);
137
            doorhanger_div.append(html_button);
138
        });
139
140
141
        $j('#password-toolbar').remove();
142
        $j('body').append(doorhanger_div);
143
        $j('#password-toolbar').slideDown();
144
    }
145
146
    _this.showDoorhanger = showDoorhanger;
147
148
    function showUrlUpdateDoorhanger(data) {
149
        var buttons = [
150
            {
151
                text: 'Cancel',
152
                onClickFn: function () {
153
                    $j('#password-toolbar').slideUp();
154
                }
155
            },
156
            {
157
                text: 'Update',
158
                onClickFn: function () {
159
                    //closeToolbar();
160
                    API.runtime.sendMessage(API.runtime.id, {method: "updateCredentialUrl", args: data.data});
161
                    $j('#password-toolbar').find('.toolbar-text').text('Saving...');
162
                    $j('#password-toolbar').find('.passman-btn').hide();
163
                }
164
            }
165
        ];
166
        showDoorhanger({
167
            data: data.data,
168
            buttons: buttons
169
        });
170
    }
171
172
    _this.showUrlUpdateDoorhanger = showUrlUpdateDoorhanger;
173
174
    function checkForMined() {
175
        if (inIframe()) {
176
            return;
177
        }
178
179
180
        API.runtime.sendMessage(API.runtime.id, {method: "getMinedData"}).then(function (data) {
181
            if (!data) {
182
                return;
183
            }
184
            if (data.hasOwnProperty('username') && data.hasOwnProperty('password') && data.hasOwnProperty('url')) {
185
                var btnText = (data.guid === null) ? 'Save' : 'Update';
186
187
                var buttons = [
188
                    {
189
                        text: 'Cancel',
190
                        onClickFn: function () {
191
                            closeToolbar();
192
                            API.runtime.sendMessage(API.runtime.id, {method: "clearMined"});
193
                        }
194
                    },
195
                    {
196
                        text: btnText,
197
                        onClickFn: function () {
198
                            //closeToolbar();
199
                            API.runtime.sendMessage(API.runtime.id, {method: "saveMined"});
200
                            $j('#password-toolbar').find('.toolbar-text').text('Saving...');
201
                            $j('#password-toolbar').find('.passman-btn').hide();
202
                        }
203
                    },
204
                    {
205
                        text: 'Ignore site',
206
                        onClickFn: function () {
207
                            //closeToolbar();
208
                            API.runtime.sendMessage(API.runtime.id, {method: "ignoreSite", args: window.location.href});
209
                            $j('#password-toolbar').find('.toolbar-text').text('Site ignored');
210
                            $j('#password-toolbar').find('.passman-btn').hide();
211
                            setTimeout(function () {
212
                                closeToolbar();
213
                            }, 3000)
214
                        }
215
                    }
216
217
                ];
218
                showDoorhanger({data: data, buttons: buttons});
219
            }
220
        });
221
    }
222
223
    function minedLoginSaved(args) {
224
        // If the login added by the user then this is true
225
        if (args.selfAdded) {
226
            enterLoginDetails(args.credential);
227
            return;
228
        }
229
        if ($j('#password-toolbar').is(':visible')) {
230
            var action = (args.updated) ? 'updated' : 'saved';
231
            $j('#password-toolbar').html('Credential ' + action + '!');
232
            setTimeout(function () {
233
                closeToolbar();
234
            }, 2500);
235
        }
236
    }
237
238
    _this.minedLoginSaved = minedLoginSaved;
239
240
    function closeToolbar() {
241
        $j('#password-toolbar').slideUp(400, function () {
242
            $j('#password-toolbar').remove();
243
        });
244
    }
245
246
    function initForms(){
247
        API.runtime.sendMessage(API.runtime.id, {method: 'getRuntimeSettings'}).then(function (result) {
248
            var disablePasswordPicker = result.disablePasswordPicker;
249
            var url = processURL(window.location.href);
250
251
            var loginFields = getLoginFields();
252
            if (loginFields.length > 0) {
253
                for (var i = 0; i < loginFields.length; i++) {
254
                    var form = getFormFromElement(loginFields[i][0]);
255
                    if (!disablePasswordPicker) {
256
                        createPasswordPicker(loginFields[i], form);
0 ignored issues
show
Bug introduced by
The call to createPasswordPicker seems to have too many arguments starting with form.
Loading history...
257
                    }
258
                    //Password miner
259
                    /* jshint ignore:start */
260
                    if(!result.hasOwnProperty('ignored_sites') || result.ignored_sites.findUrl(url) !== -1 ) {
261
                        $j(form).submit((function (loginFields) {
262
                            return function () {
263
                                formSubmitted(loginFields);
264
                            };
265
                        })(loginFields[i]));
266
                    }
267
                    /* jshint ignore:end */
268
                }
269
270
                API.runtime.sendMessage(API.runtime.id, {
271
                    method: "getCredentialsByUrl",
272
                    args: [url]
273
                }).then(function (logins) {
274
                    //console.log('Found ' + logins.length + ' logins for this site');
275
                    if (logins.length === 1) {
276
                        API.runtime.sendMessage(API.runtime.id, {method: 'isAutoFillEnabled'}).then(function (isEnabled) {
277
                            if (isEnabled) {
278
                                enterLoginDetails(logins[0]);
279
                            }
280
                        });
281
                    }
282
283
                });
284
            }
285
286
        });
287
    }
288
289
    function init() {
290
        checkForMined();
291
        initForms();
292
    }
293
294
    var readyStateCheckInterval = setInterval(function () {
295
        if (document.readyState === "complete") {
296
            clearInterval(readyStateCheckInterval);
297
            API.runtime.sendMessage(API.runtime.id, {method: 'getMasterPasswordSet'}).then(function (result) {
298
                if (result) {
299
                    init();
300
                    // var body = document.getElementsByTagName('body')[0];
301
                    // observeDOM(body, function () {
302
                    //     initForms();
303
                    // });
304
                } else {
305
                    console.log('[Passman extension] Stopping, vault key not set');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
306
                }
307
            });
308
        }
309
    }, 10);
310
311
    API.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
0 ignored issues
show
Unused Code introduced by
The parameter sendResponse is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
312
        //console.log('Method call', msg.method);
313
        if (_this[msg.method]) {
314
            _this[msg.method](msg.args, sender);
315
        }
316
    });
317
});